package com.mxl.service.channel.comm.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.mxl.common.helper.EntryCode;
import com.mxl.dao.cashorder.impl.ChargeChannelDaoImpl;
import com.mxl.dao.cashorder.impl.EntryDaoImpl;
import com.mxl.dao.cashorder.model.ChargeChannel;
import com.mxl.dao.cashorder.model.Entry;
import com.mxl.dao.cashorder.model.GatewayPayOrder;
import com.mxl.service.channel.comm.SettleChangeService;

/**
 * 商户结算信息表--现在是实时结算 后面可以商户实时结算 其他的每小时结算也可以
 * 
 * @author xianglin.mo
 * 
 */
@Service("settleChangeService")
public class SettleChangeServiceImpl implements SettleChangeService {

	@Resource(name = "chargeChannelDao")
	private ChargeChannelDaoImpl chargeChannelDao;

	private static final String CRUPDATEACCTSQL = " update acct a set a.balance = a.balance - ?,a.creditbalance=a.creditbalance+? where a.acctcode = ?";
	private static final String DRUPDATEACCTSQL = " update acct a set a.balance = a.balance + ?,a.debitbalance=a.creditbalance+? where a.acctcode = ?";

	@Resource(name = "entryDao")
	private EntryDaoImpl entryDao;

	public void Processor(String channelCode, GatewayPayOrder gorder) {
		// 查询渠道信息
		ChargeChannel c = chargeChannelDao.findUniqueBy("code", channelCode);
		List<Entry> entryList = buildEntry(c, gorder);
		for (Entry e : entryList) {
			entryDao.save(e);
			if (EntryCode.CR.getKey() == e.getCrdr()) {
				// 不支持事物回滚
				entryDao.executeSqlUpdate(CRUPDATEACCTSQL, e.getAmount(),
						e.getAmount(), e.getAcctCode());
			} else {
				entryDao.executeSqlUpdate(DRUPDATEACCTSQL, e.getAmount(),
						e.getAmount(), e.getAcctCode());
			}
		}
	}

	private List<Entry> buildEntry(ChargeChannel c, GatewayPayOrder gorder) {
		List<Entry> entryList = new ArrayList<Entry>();
		Entry e = new Entry();
		e.setAcctCode(c.getSubject());
		e.setAmount((gorder.getRealAmount() * c.getDiscount()) / 1000);// 乘以渠道折扣
		e.setAsynAccounting(EntryCode.ACCOUNTING.getKey());
		e.setCrdr(EntryCode.CR.getKey());
		Date date = new Date();
		e.setCreationDate(date);
		e.setEntryType(0);
		e.setOrderId(gorder.getSeqId());
		e.setPostDate(date);
		e.setStatus(EntryCode.POSTING_SUC.getKey());
		e.setServiceCode(EntryCode.CARD.getKey());
		entryList.add(e);
		return buildMemberEntry(entryList, gorder, c);
	}

	/**
	 * shanghu
	 * 
	 * @param channelCode
	 * @param gorder
	 * @return
	 */
	private List<Entry> buildMemberEntry(List<Entry> entryList,
			GatewayPayOrder gorder, ChargeChannel c) {
		if (gorder.getAllowAmount() > 0) {
			Entry e = new Entry();
			e.setAcctCode(gorder.getMemberCode());
			// baoliu li
			e.setAmount((gorder.getAllowAmount() * gorder.getRate()) / 1000);
			e.setAsynAccounting(EntryCode.ACCOUNTING.getKey());
			e.setCrdr(EntryCode.DR.getKey());
			Date date = new Date();
			e.setCreationDate(date);
			e.setEntryType(0);
			e.setOrderId(gorder.getSeqId());
			e.setPostDate(date);
			e.setStatus(EntryCode.POSTING_SUC.getKey());
			e.setServiceCode(EntryCode.CARD.getKey());
			entryList.add(e);
		}
		long amount = ((gorder.getRealAmount() * c.getDiscount()) - (gorder
				.getAllowAmount() * gorder.getRate())) / 1000;
		if (amount > 0) {
			return buildProfitsEntry(c, amount, gorder.getSeqId(), entryList);
		}
		return entryList;
	}

	/**
	 * shouru
	 * 
	 * @param channelCode
	 * @param gorder
	 * @return
	 */
	private List<Entry> buildProfitsEntry(ChargeChannel c, long amount,
			String seqId, List<Entry> entryList) {
		Entry e = new Entry();
		e.setAcctCode(c.getReceivingCode());
		e.setAmount(amount);
		e.setAsynAccounting(EntryCode.ACCOUNTING.getKey());
		e.setCrdr(EntryCode.DR.getKey());
		Date date = new Date();
		e.setCreationDate(date);
		e.setEntryType(0);
		e.setOrderId(seqId);
		e.setPostDate(date);
		e.setStatus(EntryCode.POSTING_SUC.getKey());
		e.setServiceCode(EntryCode.CARD.getKey());
		entryList.add(e);
		return entryList;
	}

}
